package com.chengcang.api.modules.busi.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chengcang.api.common.utils.UserUtils;
import com.chengcang.api.modules.busi.dao.BusiAddressDao;
import com.chengcang.api.modules.busi.dao.BusiDemandDao;
import com.chengcang.api.modules.busi.dao.BusiDemandTenantDao;
import com.chengcang.api.modules.busi.dao.BusiInvoiceHeadDao;
import com.chengcang.api.modules.busi.dto.*;
import com.chengcang.api.modules.busi.entity.*;
import com.chengcang.api.modules.busi.service.*;
import com.chengcang.api.modules.busi.vo.BusiAddressVo;
import com.chengcang.api.modules.busi.vo.BusiDemandDetailVO;
import com.chengcang.api.modules.busi.vo.BusiDemandVO;
import com.chengcang.api.modules.busi.vo.BusiInvoiceHeadVO;
import com.chengcang.api.modules.login.utils.UserHolder;
import com.chengcang.api.modules.sys.dao.SysTenantDao;
import com.chengcang.api.modules.sys.dto.SysProductDTO;
import com.chengcang.api.modules.sys.dto.SysUserDTO;
import com.chengcang.api.modules.sys.entity.SysTenantEntity;
import com.chengcang.api.modules.sys.service.SysDictDataService;
import com.chengcang.api.modules.sys.service.SysProductService;
import com.chengcang.common.constant.Constant;
import com.chengcang.common.enums.DataTypeEnum;
import com.chengcang.common.enums.SuperAdminEnum;
import com.chengcang.common.exception.CustomException;
import com.chengcang.common.page.PageData;
import com.chengcang.common.service.impl.CrudServiceImpl;
import com.chengcang.common.utils.ConvertUtils;
import com.chengcang.common.utils.Result;
import com.chengcang.common.utils.SnowFlakeUtils;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

/**
 * 需求实现
 *
 * @author bibajin
 * @since 1.0.0 2023-01-10
 */
@Service
@RequiredArgsConstructor
public class BusiDemandServiceImpl extends CrudServiceImpl<BusiDemandDao, BusiDemandEntity, BusiDemandDTO> implements BusiDemandService {

    private final SysTenantDao sysTenantDao;

    private final BusiDemandTenantService busiDemandTenantService;

    private final BusiDemandTenantDao busiDemandTenantDao;
    private final BusiAddressDao busiAddressDao;
    private final BusiInvoiceHeadDao busiInvoiceHeadDao;
    private final SysDictDataService sysDictDataService;
    private final BusiFinanceService busiFinanceService;

    private final BusiDemandTenantSnapshotService busiDemandTenantSnapshotService;
    private final BusiDemandProductSnapshotService busiDemandProductSnapshotService;
    private final BusiDemandAddressSnapshotService busiDemandAddressSnapshotService;
    private final BusiDemandPerformanceSnapshotService busiDemandPerformanceSnapshotService;
    private final BusiDemandDemandSnapshotService busiDemandDemandSnapshotService;
    private final BusiDemandInvoiceHeadSnapshotService busiDemandInvoiceHeadSnapshotService;

    @Override
    public QueryWrapper<BusiDemandEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<BusiDemandEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    @Override
    public PageData<BusiDemandVO> pageVo(Map<String, Object> params) {
        // 设置自身客户类型，工厂不能看到公共池中的数据
        Long tenantId = UserHolder.getUser().getDefaultTenantId();
        if (!Objects.equals(tenantId, 1L)) {
            params.put("tenantId", tenantId);
        }

        IPage<BusiDemandEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<BusiDemandVO> list = baseDao.getList(page, params);
        PageData<BusiDemandVO> pageData = getPageData(list, page.getTotal(), BusiDemandVO.class);

        complement(pageData);

        return pageData;
    }

    private BusiDemandVO selectOneForUpdate(Long id) {
        LambdaQueryWrapper<BusiDemandEntity> query = Wrappers.<BusiDemandEntity>lambdaQuery().eq(BusiDemandEntity::getId, id);
        query.last(" for update");
        BusiDemandEntity entity = baseDao.selectOne(query);
        BusiDemandVO dto = new BusiDemandVO();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(TransferOrderDTO transferOrderDto) {
        Long tenantId = UserHolder.getUser().getDefaultTenantId();

        // 修改原需求状态
        BusiDemandVO busiDemandVO = this.selectOneForUpdate(transferOrderDto.getId());
        //校验
        checkTenant(busiDemandVO.getTenantId());

        //计算新需求需求数量
        BigDecimal transferNumber = new BigDecimal(transferOrderDto.getTransferNumber());
        BigDecimal surplus = transferNumber.add(busiDemandVO.getAlreadySupplyNum());

        if (transferNumber.compareTo(BigDecimal.ZERO) < 0) {
            throw new CustomException("转单需求数量为0或小于0！");
        }
        if (surplus.compareTo(busiDemandVO.getDemandTotal()) > 0) {
            throw new CustomException("转单数量不能大于剩余需求总量！");
        }
        //更新订单状态
        busiDemandVO.setAlreadySupplyNum(surplus);
        BigDecimal total = new BigDecimal(String.valueOf(busiDemandVO.getDemandTotal()));
        BigDecimal aleadySupplyNum = new BigDecimal(String.valueOf(busiDemandVO.getAlreadySupplyNum()));
        //已完成
        if (total.compareTo(aleadySupplyNum) == 0) {
            busiDemandVO.setDemandStatus(3);
        } else {
            busiDemandVO.setDemandStatus(2);
        }
        BusiDemandDTO demandDTO = ConvertUtils.sourceToTarget(busiDemandVO, BusiDemandDTO.class);
        this.update(demandDTO);

        // 获取所有相关客户信息
        ArrayList<String> tenantIdList = Lists.newArrayList(Optional.ofNullable(transferOrderDto.getAssignIds()).orElse(new String[]{}));
        tenantIdList.add(String.valueOf(tenantId));
        List<SysTenantEntity> sysTenantEntities = sysTenantDao.selectBatchIds(tenantIdList);
        Map<Long, SysTenantEntity> map = new HashMap<>(sysTenantEntities.size());
        if (CollectionUtils.isNotEmpty(sysTenantEntities)) {
            map = sysTenantEntities.stream().collect(Collectors.toMap(SysTenantEntity::getId, Function.identity()));
        }
        // 当前客户信息
        SysTenantEntity tenantEntity = map.get(tenantId);

        //新建需求
        BusiDemandDTO busiDemandDTO = newBusiDemandInsert(busiDemandVO, tenantEntity, transferNumber);
        busiFinanceInsert(busiDemandDTO, NumberUtil.mul(busiDemandDTO.getPrice(), busiDemandDTO.getDemandTotal()).setScale(6, RoundingMode.UP));

        //处理关联关系
        if (2 == transferOrderDto.getType() && null != transferOrderDto.getAssignIds()) {
            demandAssignInsert(transferOrderDto.getAssignIds(), busiDemandVO.getTenantId(), tenantId, busiDemandDTO.getInvoiceTypeId());
        }

    }

    /**
     * 转单新需求增加
     *
     * @param busiDemandVO
     * @param tenantEntity
     * @param transferNumber
     * @return
     */
    private BusiDemandDTO newBusiDemandInsert(BusiDemandVO busiDemandVO, SysTenantEntity tenantEntity, BigDecimal transferNumber) {
        BusiDemandDTO newBusiDemandDTO = new BusiDemandDTO();
        BeanUtils.copyProperties(busiDemandVO, newBusiDemandDTO);
        //设置转单需求初始化数据
        newBusiDemandDTO.setDemandTotal(transferNumber);
        newBusiDemandDTO.setTenantId(tenantEntity.getId());
        newBusiDemandDTO.setAlreadySupplyNum(BigDecimal.ZERO);
        newBusiDemandDTO.setDemandSourceType(1); //转发
        newBusiDemandDTO.setDemandStatus(2);
        newBusiDemandDTO.setDemandNo(SnowFlakeUtils.getNextId());
        newBusiDemandDTO.setCreator(UserHolder.getUserId());
        newBusiDemandDTO.setCreateDate(new Date());
        newBusiDemandDTO.setUpdateDate(new Date());
        newBusiDemandDTO.setPerformanceId(null);
        newBusiDemandDTO.setId(null);
        newBusiDemandDTO.setTenantName(tenantEntity.getName());
        newBusiDemandDTO.setTenantType(tenantEntity.getTenantType());
        this.save(newBusiDemandDTO);
        return newBusiDemandDTO;
    }

    private void checkTenant(Long demandId) {
        SysTenantEntity demandTenantEntity = sysTenantDao.selectById(demandId);
        Optional.ofNullable(demandTenantEntity).orElseThrow(() -> new CustomException("需求数据异常，缺少tenantId数据！"));
        SysUserDTO user = UserHolder.getUser();
        if (user.getTenantType() == 2) {
            throw new CustomException("散户不允许转单！");
        }
        if (user.getTenantType() == 0) {
            throw new CustomException("工厂不允许转单！");
        }
        if (Objects.equals(demandTenantEntity.getTenantType(), user.getTenantType())) {
            throw new CustomException("不允许接同类型用户的订单！");
        }

        //需求来源为公司不允许转单
        if (demandTenantEntity.getTenantType().equals(1)) {
            throw new CustomException("公司类型的需求不允许转单！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDemand(BusiDemandDTO dto) {
        //系统管理员，不能新建需求
        if (UserUtils.isSuperAdmin()) {
            log.error("超级管理员不允许新建需求！");
            throw new CustomException("超级管理员不允许新建需求！");
        }
        Long tenantId = UserHolder.getUser().getDefaultTenantId();

        //计算税金额  ----这里先设置为null,后续需要做处理
        //卖家收款金额 单价乘以数量
        BigDecimal sellerReceivePrice = dto.getPrice().multiply(dto.getDemandTotal()).setScale(6, RoundingMode.UP);
        //税率
        BigDecimal taxRate = new BigDecimal("0.001");
        //服务费率
        BigDecimal serviceRate = new BigDecimal("0.001");
        // 1
        BigDecimal unit1 = new BigDecimal(1);
        //不含增值税金额
        dto.setNoVatPrice(sellerReceivePrice.multiply((serviceRate.add(unit1))).setScale(2,RoundingMode.UP));
        //增值税
        dto.setVat(sellerReceivePrice.multiply(taxRate.divide(
                unit1.subtract(taxRate), 6,RoundingMode.UP)).setScale(2,RoundingMode.UP));
        //合同总价
        dto.setContractTotalPrice(sellerReceivePrice
                .multiply((unit1.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP));
        //卖家收款金额
        dto.setSellerReceivePrice(sellerReceivePrice);
        //平台代收税费
        dto.setPlatformTakeTaxPrice(sellerReceivePrice.multiply(
                (taxRate.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP));

        //BusiDemandEntity busiDemandEntity = new BusiDemandEntity();
        //保存需求表数据
        //BeanUtils.copyProperties(dto, busiDemandEntity);
        dto.setDemandNo(String.valueOf(SnowFlakeUtils.getInstance().nextId()));
        dto.setDataSource(0);
        dto.setDemandStatus(2);
        dto.setPayStatus(1);//支付状态0  已支付
        //新增一条支付记录
        busiFinanceInsert(dto, sellerReceivePrice);

        dto.setTenantId(tenantId);
        dto.setDemandId(tenantId);
        if (dto.getAssignIds() != null && dto.getAssignIds().length > 0) {
            dto.setAssignType(0);
        } else {
            dto.setAssignType(1);
        }
        demandSnapshotSave(dto);
        this.save(dto);

        demandAssignInsert(dto.getAssignIds(), tenantId, tenantId, dto.getInvoiceTypeId());

    }

    /**
     * 支付记录
     *
     * @param dto
     * @param sellerReceivePrice
     */
    private void busiFinanceInsert(BusiDemandDTO dto, BigDecimal sellerReceivePrice) {
        BusiFinanceDTO busiFinanceDTO = new BusiFinanceDTO();
        busiFinanceDTO.setDemandId(dto.getDemandId());
        busiFinanceDTO.setDemandNo(dto.getDemandNo());
        busiFinanceDTO.setOrderAmount(sellerReceivePrice);
        busiFinanceDTO.setOrderStatus(1);
        busiFinanceDTO.setPayWay(0);
        busiFinanceDTO.setOrderSourceType(0);
        busiFinanceDTO.setSupplyId(null);
        busiFinanceDTO.setCreateDate(new Date());
        busiFinanceDTO.setUpdateDate(new Date());
        busiFinanceService.save(busiFinanceDTO);
    }

    /**
     * 添加需求客户关联表
     *
     * @param assignIds     指派方客户ID
     * @param demandId      需求方客户ID
     * @param tenantId      甲方客户ID
     * @param invoiceTypeId 发票类型ID
     */
    private void demandAssignInsert(String[] assignIds, Long demandId, Long tenantId, Long invoiceTypeId) {
        List<BusiDemandTenantEntity> demandTenantEntities = new ArrayList<>();
        if (assignIds != null && assignIds.length > 0) {
            for (String assignId : assignIds) {
                BusiDemandTenantEntity busiDemandTenantEntity = new BusiDemandTenantEntity();
                busiDemandTenantEntity.setAssignId(Long.valueOf(assignId));
                busiDemandTenantEntity.setTenantId(tenantId);
                busiDemandTenantEntity.setDemandId(demandId);
                busiDemandTenantEntity.setInvoiceTypeId(invoiceTypeId);
                demandTenantEntities.add(busiDemandTenantEntity);
            }
        }
        busiDemandTenantService.insertBatch(demandTenantEntities);
    }

    private void demandSnapshotSave(BusiDemandDTO dto) {
        BusiDemandAddressSnapshotEntity addressSnapshotEntity = busiDemandAddressSnapshotService.saveDemandSnapshot(dto.getId(), dto.getAddressId());
        dto.setAddressId(addressSnapshotEntity.getId());
        BusiDemandProductSnapshotEntity productSnapshotEntity = busiDemandProductSnapshotService.saveDemandSnapshot(dto.getId(), dto.getProductId());
        dto.setProductId(productSnapshotEntity.getId());
        BusiDemandInvoiceHeadSnapshotEntity invoiceHeadSnapshotEntity = busiDemandInvoiceHeadSnapshotService.saveDemandSnapshot(dto.getId(), dto.getInvoiceHeadId());
        dto.setInvoiceHeadId(invoiceHeadSnapshotEntity.getId());
       /* BusiDemandTenantSnapshotEntity demandTenantSnapshotEntity = busiDemandTenantSnapshotService.saveDemandSnapshot(dto.getId(), dto.getTenantId());
        dto.setTenantId(demandTenantSnapshotEntity.getId());
        BusiDemandDemandSnapshotEntity demandDemandSnapshotEntity = busiDemandDemandSnapshotService.saveDemandSnapshot(dto.getId(), dto.getDemandId());
        dto.setDemandId(demandDemandSnapshotEntity.getId());*/
        //供应方待定
        //busiDemandPerformanceSnapshotService.saveDemandSnapshot(dto.getDemandId(), dto.getPerformanceId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeDemand(Long id, String reason) {

        BusiDemandEntity busiDemandEntity = this.selectById(id);
        if (busiDemandEntity.getDemandStatus().equals(1)) {
            throw new CustomException("不能关闭正在履约的需求！！！");
        }
        //需求客户关系表更新
        LambdaUpdateWrapper<BusiDemandTenantEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(id != null, BusiDemandTenantEntity::getDemandId, id).set(BusiDemandTenantEntity::getDeleted, 1);
        busiDemandTenantDao.update(null, updateWrapper);
        //更新需求表的状态
        LambdaUpdateWrapper<BusiDemandEntity> demandEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        demandEntityLambdaUpdateWrapper.eq(id != null, BusiDemandEntity::getId, id).set(BusiDemandEntity::getCloseReason, reason).set(BusiDemandEntity::getDemandStatus, 4);
        baseDao.update(null, demandEntityLambdaUpdateWrapper);
    }

    @Override
    public BusiDemandDetailVO getDeamndDetailByTenantId(Long id) {
        //查询需求
        BusiDemandEntity busiDemandEntity = baseDao.selectById(id);
        Optional.ofNullable(busiDemandEntity).orElseThrow(() -> new CustomException("未查到需求!"));

        BusiDemandDetailVO busiDemandDetailVO = ConvertUtils.sourceToTarget(busiDemandEntity, BusiDemandDetailVO.class);
        busiDemandDetailVO.setDemandId(busiDemandEntity.getId());
        //获取计量单位字典值 快照表查询数据
        BusiDemandProductSnapshotDTO productSnapshotDTO = busiDemandProductSnapshotService.get(busiDemandEntity.getProductId());
        if (productSnapshotDTO != null && StringUtils.isNotBlank(productSnapshotDTO.getSpec())) {
            busiDemandDetailVO.setProductUnit(sysDictDataService.getJoiningValue(DataTypeEnum.PRODUCT_UNIT, String.valueOf(busiDemandEntity.getProductUnit())));
        }
        //查询商品信息获取商品类别
        Optional.ofNullable(productSnapshotDTO).ifPresent(o -> {
            busiDemandDetailVO.setProductCategory(productSnapshotDTO.getFirstParentName() + ">" + productSnapshotDTO.getSecondParentName() + ">" + productSnapshotDTO.getName());
            busiDemandDetailVO.setProductName(productSnapshotDTO.getName());
        });
        //需求状态
        if (busiDemandEntity.getDemandStatus() != null) {
            busiDemandDetailVO.setDemandStatusName(sysDictDataService.getValue(DataTypeEnum.DEMAND_STATUS, String.valueOf(busiDemandEntity.getDemandStatus())));
        }
        //支付状态
        if (busiDemandEntity.getPayStatus() != null) {
            busiDemandDetailVO.setPayStatusName(sysDictDataService.getValue(DataTypeEnum.PAY_STATUS, String.valueOf(busiDemandEntity.getPayStatus())));
        }

        //补全收货地址 快照表读数据
        //补全收货地址 快照获取
        BusiDemandAddressSnapshotDTO addressSnapshotDTO = busiDemandAddressSnapshotService.get(busiDemandDetailVO.getAddressId());
        Optional.ofNullable(addressSnapshotDTO).ifPresent(o -> complementAddress(busiDemandDetailVO, addressSnapshotDTO));
        // 补全发票抬头信息 快照获取
        BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotDTO = busiDemandInvoiceHeadSnapshotService.get(busiDemandDetailVO.getInvoiceHeadId());
        Optional.ofNullable(invoiceHeadSnapshotDTO).ifPresent(o -> complementInvoiceHead(busiDemandDetailVO, invoiceHeadSnapshotDTO));

        if (null != busiDemandDetailVO.getDemandId() && StringUtils.isBlank(busiDemandDetailVO.getDemandName())) {
            SysTenantEntity sysTenantEntity = sysTenantDao.selectById(busiDemandDetailVO.getDemandId());
            Optional.ofNullable(sysTenantEntity).ifPresent(o -> busiDemandDetailVO.setDemandName(o.getName()));
        }
        if (null != busiDemandDetailVO.getTenantId() && StringUtils.isBlank(busiDemandDetailVO.getTenantName())) {
            SysTenantEntity sysTenantEntity = sysTenantDao.selectById(busiDemandDetailVO.getTenantId());
            Optional.ofNullable(sysTenantEntity).ifPresent(o -> busiDemandDetailVO.setTenantName(o.getName()));
        }

        return busiDemandDetailVO;
    }

    private void complementAddress(BusiDemandDetailVO busiDemandDetailVO, BusiDemandAddressSnapshotDTO addressSnapshotDTO) {
        Optional.ofNullable(busiDemandDetailVO).ifPresent(vo -> {
            vo.setAddressId(addressSnapshotDTO.getId());
            vo.setTag(addressSnapshotDTO.getTag());
            vo.setAddress(addressSnapshotDTO.getAddress());
            vo.setConsignee(addressSnapshotDTO.getConsignee());
            vo.setAddressMobile(addressSnapshotDTO.getAddressMobile());
            vo.setProvinceId(addressSnapshotDTO.getProvinceId());
            vo.setProvinceName(addressSnapshotDTO.getProvinceName());
            vo.setCityId(addressSnapshotDTO.getCityId());
            vo.setCityName(addressSnapshotDTO.getCityName());
            vo.setAreaId(addressSnapshotDTO.getAreaId());
            vo.setAreaName(addressSnapshotDTO.getAreaName());
        });
    }

    private void complementInvoiceHead(BusiDemandDetailVO busiDemandDetailVO, BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotDTO) {
        Optional.ofNullable(busiDemandDetailVO).ifPresent(vo -> {
            vo.setInvoiceHeadId(invoiceHeadSnapshotDTO.getId());
            vo.setInvoiceTypeName(sysDictDataService.getValue(DataTypeEnum.INVOICE_TYPE, String.valueOf(invoiceHeadSnapshotDTO.getInvoiceType())));
            vo.setInvoiceType(invoiceHeadSnapshotDTO.getInvoiceType());
            vo.setInvoiceCode(invoiceHeadSnapshotDTO.getInvoiceCode());
            vo.setInvoiceHead(invoiceHeadSnapshotDTO.getInvoiceHead());
            vo.setInvoiceBankAccount(invoiceHeadSnapshotDTO.getInvoiceBankAccount());
            vo.setInvoiceMobile(invoiceHeadSnapshotDTO.getInvoiceMobile());
            vo.setInvoiceBankName(invoiceHeadSnapshotDTO.getInvoiceBankName());
            vo.setInvoiceAddress(invoiceHeadSnapshotDTO.getInvoiceAddress());
            vo.setInvoiceEmail(invoiceHeadSnapshotDTO.getInvoiceEmail());
        });

    }

    @Override
    public Result<BusiDemandDetailVO> getInvoiceAndAddress(Long demandId) {
        //系统管理员，不能新建需求
        if (UserUtils.isSuperAdmin()) {
            log.error("超级管理员不允许新建需求！");
            throw new CustomException("超级管理员不允许新建需求！");
        }
        Long tenantId = UserHolder.getUser().getDefaultTenantId();
        if (demandId != null) {
            tenantId = demandId;
        }

        //获取发票字典值
        BusiDemandDetailVO busiDemandDetailVO = new BusiDemandDetailVO();

        // 补全地址
        LambdaQueryWrapper<BusiAddressEntity> queryWrapper = new LambdaQueryWrapper<BusiAddressEntity>().eq(BusiAddressEntity::getTenantId, tenantId).eq(BusiAddressEntity::getDefaulted, 0);
        BusiAddressEntity busiAddressEntity = busiAddressDao.selectOne(queryWrapper);
        if (busiAddressEntity == null) {
            log.error("未查到该租户下收货信息");
            throw new CustomException("未查到该租户下收货信息");
        }
        BusiDemandAddressSnapshotDTO addressSnapshotDTO = ConvertUtils.sourceToTarget(busiAddressEntity, BusiDemandAddressSnapshotDTO.class);
        complementAddress(busiDemandDetailVO, addressSnapshotDTO);
        // 补全发票抬头
        //查询发票信息
        LambdaQueryWrapper<BusiInvoiceHeadEntity> queryWrapperBusiInvoiceHead = new LambdaQueryWrapper<BusiInvoiceHeadEntity>().eq(BusiInvoiceHeadEntity::getTenantId, tenantId).eq(BusiInvoiceHeadEntity::getDefaulted, 0);
        BusiInvoiceHeadEntity busiInvoiceHeadEntity = busiInvoiceHeadDao.selectOne(queryWrapperBusiInvoiceHead);
        if (busiInvoiceHeadEntity == null) {
            log.error("未查到该租户下发票信息");
            throw new CustomException("未查到该租户下发票信息");
        }
        BusiDemandInvoiceHeadSnapshotDTO invoiceHeadSnapshotDTO = ConvertUtils.sourceToTarget(busiInvoiceHeadEntity, BusiDemandInvoiceHeadSnapshotDTO.class);
        complementInvoiceHead(busiDemandDetailVO, invoiceHeadSnapshotDTO);

        return new Result<BusiDemandDetailVO>().ok(busiDemandDetailVO);
    }

    @Override
    public PageData<BusiDemandVO> appoint(Map<String, Object> params) {
        // 设置自身客户类型，工厂不能看到公共池中的数据
        Long tenantId = UserHolder.getUser().getDefaultTenantId();
        Optional.ofNullable(tenantId).ifPresent(o -> params.put("tenantId", tenantId));
        if (tenantId != null) {
            SysTenantEntity sysTenantEntity = sysTenantDao.selectById(tenantId);
            params.put("tenantSelfType", sysTenantEntity.getTenantType());
        }

        IPage<BusiDemandEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<BusiDemandVO> list = baseDao.getAppointList(page, params);

        PageData<BusiDemandVO> pageData = getPageData(list, page.getTotal(), BusiDemandVO.class);

        complement(pageData);

        return pageData;
    }

    private void complement(PageData<BusiDemandVO> pageData) {
        List<BusiDemandVO> list = pageData.getList();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        //履约方客户ID
        Set<Long> performanceIdList = list.stream().filter(o -> StringUtils.isNotBlank(o.getPerformanceId())).flatMap(o -> Arrays.stream(o.getPerformanceId().split(","))).map(Long::parseLong).collect(toSet());
        Map<Long, Integer> tenantTypeMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(performanceIdList)) {
            tenantTypeMap = sysTenantDao.selectBatchIds(performanceIdList).stream().collect(toMap(SysTenantEntity::getId, SysTenantEntity::getTenantType));
        }
        // 甲方客户ID
        Set<Long> tenantIdList = list.stream().map(BusiDemandVO::getTenantId).collect(toSet());
        Map<Long, String> tenantMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(tenantIdList)) {
            tenantMap = sysTenantDao.selectBatchIds(tenantIdList).stream().collect(toMap(SysTenantEntity::getId, SysTenantEntity::getName));
        }
        // 查询地址详情
        List<Long> addressIds = list.stream().map(BusiDemandVO::getAddressId).collect(toList());
        List<BusiDemandAddressSnapshotDTO> addressSnapshotDTOS = busiDemandAddressSnapshotService.selectBatchIds(addressIds);
        Map<Long, BusiAddressVo> addressMap = addressSnapshotDTOS.stream().collect(toMap(BusiDemandAddressSnapshotDTO::getId, o -> ConvertUtils.sourceToTarget(o, BusiAddressVo.class)));

        // 发票抬头信息
        List<Long> invoiceHeadIds = list.stream().map(BusiDemandVO::getInvoiceHeadId).collect(toList());
        List<BusiDemandInvoiceHeadSnapshotDTO> invoiceHeadSnapshotDTOS = busiDemandInvoiceHeadSnapshotService.selectBatchIds(invoiceHeadIds);
        Map<Long, BusiInvoiceHeadVO> invoiceHeadVOMap = invoiceHeadSnapshotDTOS.stream().collect(toMap(BusiDemandInvoiceHeadSnapshotDTO::getId, o -> ConvertUtils.sourceToTarget(o, BusiInvoiceHeadVO.class)));

        for (BusiDemandVO busiDemandVO : list) {
            Optional.ofNullable(busiDemandVO.getAddressId()).ifPresent(o -> busiDemandVO.setBusiAddressVo(addressMap.get(busiDemandVO.getAddressId())));
            Optional.ofNullable(busiDemandVO.getInvoiceHeadId()).ifPresent(o -> {
                BusiInvoiceHeadVO invoiceHeadVO = invoiceHeadVOMap.get(busiDemandVO.getInvoiceHeadId());
                Optional.ofNullable(invoiceHeadVO).ifPresent(o1 -> invoiceHeadVO.setInvoiceTypeName(sysDictDataService.getValue(DataTypeEnum.INVOICE_TYPE, String.valueOf(invoiceHeadVO.getInvoiceType()))));
                busiDemandVO.setInvoiceHeadVO(invoiceHeadVO);
            });

            //客户类型(履约客户)
            Map<Long, Integer> finalTenantTypeMap = tenantTypeMap;
            Optional.ofNullable(busiDemandVO.getPerformanceId()).ifPresent(o -> {
                List<Long> performanceIds = Arrays.stream(busiDemandVO.getPerformanceId().split(",")).map(Long::parseLong).collect(toList());
                List<String> performanceNameList = new ArrayList<>();
                for (Long performanceId : performanceIds) {
                    performanceNameList.add(sysDictDataService.getValue(DataTypeEnum.TENANT_TYPE, String.valueOf(finalTenantTypeMap.get(performanceId))));
                }
                busiDemandVO.setPerformanceName(String.join(",", performanceNameList));
            });
            //需求货品
            BusiDemandProductSnapshotDTO productSnapshotDTO = busiDemandProductSnapshotService.get(busiDemandVO.getProductId());
            Optional.ofNullable(productSnapshotDTO).ifPresent(o -> {
                busiDemandVO.setProductName(productSnapshotDTO.getName());
                busiDemandVO.setProductCategory(productSnapshotDTO.getFirstParentName() + "-" + productSnapshotDTO.getSecondParentName() + "-" + productSnapshotDTO.getName());
            });
            busiDemandVO.setTenantName(tenantMap.get(busiDemandVO.getTenantId()));
            Optional.ofNullable(busiDemandVO.getDemandStatus()).ifPresent(o -> busiDemandVO.setDemandStatusName(sysDictDataService.getValue(DataTypeEnum.DEMAND_STATUS, String.valueOf(o))));
            Optional.ofNullable(busiDemandVO.getPayStatus()).ifPresent(o -> busiDemandVO.setPayStatusName(sysDictDataService.getValue(DataTypeEnum.PAY_STATUS, String.valueOf(o))));
            Optional.ofNullable(busiDemandVO.getDataSource()).ifPresent(o -> busiDemandVO.setDataSourceName(sysDictDataService.getValue(DataTypeEnum.DATA_SOURCE, String.valueOf(o))));
            //需求来源类型
            Optional.ofNullable(busiDemandVO.getDemandSourceType()).ifPresent(o -> busiDemandVO.setDemandSourceTypeName(sysDictDataService.getValue(DataTypeEnum.DEMAND_SOURCE_TYPE, String.valueOf(o))));
            //需求去向类型
            Optional.ofNullable(busiDemandVO.getAssingType()).ifPresent(o -> busiDemandVO.setAssingTypeName(sysDictDataService.getValue(DataTypeEnum.DEMAND_DIRECTION_TYPE, String.valueOf(o))));
            //获取计量单位字典值
            if (productSnapshotDTO != null && StringUtils.isNotBlank(productSnapshotDTO.getSpec())) {
                busiDemandVO.setProductUnit(sysDictDataService.getJoiningValue(DataTypeEnum.PRODUCT_UNIT, String.valueOf(busiDemandVO.getProductUnit())));
            }
        }
    }
}
